
#pragma once

#include "GLvec3.h"
#include "GLbbox.h"

class GLray
{
public:
	GLvec3f m_org,dir;
public:
	GLray(){}
	GLray( GLvec3f& org,GLvec3f&dir ){ m_org = org,dir = dir; }
	
	bool InsectTrangle( const GLvec3f & v0, const GLvec3f& v1,const GLvec3f& v2 ,GLvec3f& tuv)
	{
		// Find vectors for two edges sharing vert0.
		const GLvec3f e1 = v1 - v0;
		const GLvec3f e2 = v2 - v0;

		const float EPSILON =  1e-4f; 

		// Begin calculating determinant - also used to calculate U parameter.
		const GLvec3f pvec = dir.CrossProd( e2 );

		// If determinant is near zero, ray lies in plane of triangle.
		const float det = e1.DotProd( pvec );

		if(det > -EPSILON && det < EPSILON)
			return false;

		const float inv_det = 1.0f / det;

		// Calculate distance from vert0 to ray origin.
		GLvec3f tvec = m_org - v0;

		//if( det < 0.f )
			//tvec.Scale( -1.f );

		// Calculate U parameter and test bounds.
		tuv.y = (tvec.DotProd(pvec)) * inv_det;
		
		if(tuv.y < 0.0 || tuv.y > 1.0)
			return false;

		// Prepare to test V parameter.
		const GLvec3f qvec = tvec.CrossProd(e1);

		// Calculate V parameter and test bounds.
		tuv.z = ( dir.DotProd( qvec)) * inv_det;
		
		if(tuv.z < 0.0 || tuv.y + tuv.z > 1.0)
			return false;

		// Calculate t, ray intersects triangle.
		tuv.x = (e2.DotProd(qvec)) * inv_det;

		return true;
	}

	bool InsectBox( const GLbbox& box)
	{
		GLvec3f triVerts[36];
		box.GetTriVerts( triVerts );

		for( int i = 0;i<12;i++ )
		{
			GLvec3f v;
		
			if( InsectTrangle( triVerts[i*3],triVerts[i*3+1],triVerts[i*3+2],v ) )
				return true;
		}
		
		return false;
	}
};